﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Json;
using System.Text;
using System.Threading;
using System.IO;
using System.Windows.Markup;
using System.Diagnostics;

namespace BingApp
{
    public partial class MainPage : UserControl
    {
        const string APPID = "1369A68D3D83D36A0CF025458F3AD678B4FF33BF";
        string search_query = "";
        List<BingWebResult> BingWebResults = new List<BingWebResult>();
        List<BingImageResult> BingImagesResults = new List<BingImageResult>();
        public ManualResetEvent allDone = new ManualResetEvent(false);
        const int BUFFER_SIZE = 1024;
        string query_string = "http://api.bing.net/json.aspx?AppId=";
        
        HttpWebRequest web_request;
     
        public MainPage()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            QueryTextBox.SelectAll();
        }

        private void SearchButton_Click(object sender, RoutedEventArgs e)
        {
            //Content = new Results(); = navigate to new page
            if (QueryTextBox.Text != string.Empty)
            {
                search_query = QueryTextBox.Text;
                getBingResults(QueryTextBox.Text);
            }
        }

        private void getBingResults(string query)
        {
            try
            {
                query_string += APPID + "&Query=" + query + "&Sources=web&Sources=image&Sources=video&Web.Offset=50&Image.Offset=50&Video.Offset=50&Image.Count=50&Web.Count=50&Video.Count=50";
                web_request = (HttpWebRequest)WebRequest.Create(query_string);

                RequestState requestWebState = new RequestState();
                requestWebState.webRequest = web_request;

                requestWebState.webRequest.BeginGetResponse(new AsyncCallback(ResponseCallback), requestWebState);
            }
            catch (Exception err)
            {
                
            }
        }

        // helper methods here....

        private void ResponseCallback(IAsyncResult asynchronousResult)
        {
            try
            {
                RequestState myRequestState = (RequestState)asynchronousResult.AsyncState;
                WebRequest myWebRequest = myRequestState.webRequest;
                myRequestState.webResponse = myWebRequest.EndGetResponse(asynchronousResult);

                Stream responseStream = myRequestState.webResponse.GetResponseStream();
                myRequestState.responseStream = responseStream;

                IAsyncResult asynchronousResultRead = responseStream.BeginRead(myRequestState.bufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);

            }
            catch (Exception err)
            {
            }
        }

        private void ReadCallBack(IAsyncResult asyncResult)
        {
            // Result state is set to AsyncState.
            RequestState myRequestState = (RequestState)asyncResult.AsyncState;
            Stream responseStream = myRequestState.responseStream;
            int read = responseStream.EndRead(asyncResult);
            // Read the contents of the JSON result
            if (read > 0)
            {
                myRequestState.requestData.Append(Encoding.UTF8.GetString(myRequestState.bufferRead, 0, read));
                IAsyncResult asynchronousResult = responseStream.BeginRead(myRequestState.bufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), myRequestState);
            }
            else
            {
                if (myRequestState.requestData.Length > 1)
                {
                    string stringContent;
                    stringContent = myRequestState.requestData.ToString();

                    processBingJSONResults(stringContent);

                    showResults r = new showResults(showResultsPage);
                    this.Dispatcher.BeginInvoke(r, new object[]
                        {
                            BingWebResults,
                            BingImagesResults
                        });
                }
                responseStream.Close();
                allDone.Set();
            }

        }

        delegate void showResults(List<BingWebResult> res, List<BingImageResult> img);
        private void showResultsPage(List<BingWebResult> web_list, List<BingImageResult> img_list)
        {
            try
            {
                Results resultsPage = new Results();
                resultsPage.webProperty = web_list;
                resultsPage.imageProperty = img_list;
                resultsPage.searchQuery = search_query;
                Content = resultsPage;
            }
            catch (Exception e)
            {
            }
        }

        delegate void processResults(string results);

        private void processBingJSONResults(string json_results)
        {
            try
            {
                JsonValue bing_results = JsonValue.Parse(json_results);
                JsonValue bing_web_result;
                JsonArray bing_results_array = null;
                if (bing_results.ContainsKey("SearchResponse"))
                    bing_results = bing_results["SearchResponse"];

                if (bing_results.ContainsKey("Web"))
                {
                    bing_web_result = bing_results["Web"];

                    if (bing_web_result.ContainsKey("Results")) //found results
                    {
                        bing_results_array = (JsonArray)bing_web_result["Results"];
                        if (bing_results.Count > 0)
                        {
                            for (int i = 0; i < bing_results_array.Count; i++)
                            {
                                JsonValue bingResultElement = bing_results_array[i];
                                BingWebResult bingResult = new BingWebResult();
                                if (bingResultElement.ContainsKey("Title"))
                                    bingResult.BingResultTitle = bingResultElement["Title"].ToString().Replace("\"", string.Empty);
                                if (bingResultElement.ContainsKey("Description"))
                                    bingResult.BingResultDescription = bingResultElement["Description"].ToString().Replace("\"", string.Empty);
                                if (bingResultElement.ContainsKey("Url"))
                                    bingResult.BingResultUrl = bingResultElement["Url"].ToString().Replace("\"", string.Empty).Replace("\\", string.Empty);
                                if (bingResultElement.ContainsKey("CacheUrl"))
                                    bingResult.BingResultCacheUrl = bingResultElement["CacheUrl"].ToString().Replace("\"", string.Empty);
                                if (bingResultElement.ContainsKey("DisplayUrl"))
                                    bingResult.BingResultDisplayUrl = bingResultElement["DisplayUrl"].ToString().Replace("\"", string.Empty);
                                if (bingResultElement.ContainsKey("DateTime"))
                                    bingResult.BingResultdateTime = (DateTime)bingResultElement["DateTime"];

                                BingWebResults.Add(bingResult);
                            }
                        }
                    }
                }
                if (bing_results.ContainsKey("Image"))
                {
                    bing_results = bing_results["Image"];
                    if (bing_results.ContainsKey("Results"))
                    {
                        bing_results_array = (JsonArray)bing_results["Results"];
                        if (bing_results_array.Count > 0)
                        {
                            for (int i = 0; i < bing_results_array.Count; i++)
                            {
                                JsonValue bing_image_result = bing_results_array[i];
                                BingImageResult image_result = new BingImageResult();
                                if (bing_image_result.ContainsKey("Thumbnail"))
                                    image_result.BingResultImageThumbnail = (string)bing_image_result["Thumbnail"]["Url"];
                                if (bing_image_result.ContainsKey("MediaUrl"))
                                    image_result.BingResultImageMedia = (string)bing_image_result["MediaUrl"];
                                if (bing_image_result.ContainsKey("Title"))
                                    image_result.BingResultImageTitle = (string)bing_image_result["Title"];

                                BingImagesResults.Add(image_result);
                            }
                        }
                    }
                }
            }
            catch (Exception err)
            {
            }
        }

        private void QueryTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && QueryTextBox.Text != null)
            {
                search_query = QueryTextBox.Text;
                getBingResults(QueryTextBox.Text);
            }
        }
    }
}







public class RequestState
{
    const int BUFFER_SIZE = 1024;
    public StringBuilder requestData;
    public byte[] bufferRead;
    public WebRequest webRequest;
    public WebResponse webResponse;
    public Stream responseStream;

    public RequestState()
    {
        requestData = new StringBuilder("");
        bufferRead = new byte[BUFFER_SIZE];
        responseStream = null;
        webRequest = null;
        webResponse = null;
    }
}